package com.jyt.peripheral.print.test;

import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewParent;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.caysn.printerlibs.printerlibs_caysnpos.printerlibs_caysnpos;
import com.jyt.peripheral.R;
import com.sun.jna.Pointer;
import com.sun.jna.WString;
import com.sun.jna.ptr.IntByReference;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class ActivityMain extends Activity implements OnClickListener {

    private ActivityMain activity;
    private LinearLayout layoutMain;
    private GRadioGroup rgPort;
    private RadioButton rbBT2, rbBT4, rbNET, rbUSB, rbCOM;
    private ComboBox cbxListBT2, cbxListBT4, cbxListNET, cbxListUSB, cbxListCOMPort, cbxListCOMBaud;
    private CheckBox chkListenBT2;
    private Button btnEnumPort, btnOpenPort, btnClosePort;
    private ListView listViewTestFunction;

    private static final int nBaudTable[] = {1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 256000, 500000, 750000, 1125000, 1500000};

    private Pointer h = Pointer.NULL;
    printerlibs_caysnpos.on_port_closed_callback closed_callback = new printerlibs_caysnpos.on_port_closed_callback() {
        @Override
        public void on_port_closed(Pointer private_data) {
            ActivityMain.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    ClosePort();
                }
            });
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle(printerlibs_caysnpos.INSTANCE.CaysnPos_LibraryVersion());

        activity = this;

        layoutMain = (LinearLayout) findViewById(R.id.layoutMain);
        rbBT2 = (RadioButton) findViewById(R.id.rbBT2);
        rbBT4 = (RadioButton) findViewById(R.id.rbBT4);
        rbNET = (RadioButton) findViewById(R.id.rbNET);
        rbUSB = (RadioButton) findViewById(R.id.rbUSB);
        rbCOM = (RadioButton) findViewById(R.id.rbCOM);
        cbxListBT2 = (ComboBox) findViewById(R.id.cbxLisbBT2);
        cbxListBT4 = (ComboBox) findViewById(R.id.cbxLisbBT4);
        cbxListNET = (ComboBox) findViewById(R.id.cbxListNET);
        cbxListUSB = (ComboBox) findViewById(R.id.cbxLisbUSB);
        cbxListCOMPort = (ComboBox) findViewById(R.id.cbxListCOMPort);
        cbxListCOMBaud = (ComboBox) findViewById(R.id.cbxListCOMBaud);
        chkListenBT2 = (CheckBox) findViewById(R.id.chkListenBT2);
        btnEnumPort = (Button) findViewById(R.id.btnEnumPort);
        btnOpenPort = (Button) findViewById(R.id.btnOpenPort);
        btnClosePort = (Button) findViewById(R.id.btnClosePort);
        listViewTestFunction = (ListView) findViewById(R.id.listViewTestFunction);

        for (int baud : nBaudTable) {
            cbxListCOMBaud.addString("" + baud);
        }
        cbxListCOMBaud.setText("115200");

        btnEnumPort.setOnClickListener(this);
        btnOpenPort.setOnClickListener(this);
        btnClosePort.setOnClickListener(this);

        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, TestFunction.testFunctionOrderedList);
        listViewTestFunction.setAdapter(adapter);
        listViewTestFunction.setOnItemClickListener(onTestFunctionClicked);

        rgPort = new GRadioGroup(rbBT2, rbBT4, rbNET, rbUSB, rbCOM);
        rbBT2.performClick();
        btnEnumPort.performClick();
        RefreshUI();
    }

    @Override
    protected void onDestroy() {
        btnClosePort.performClick();
        super.onDestroy();
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.btnEnumPort) {
            EnumPort();
        } else if (id == R.id.btnOpenPort) {
            OpenPort();
        } else if (id == R.id.btnClosePort) {
            ClosePort();
        }
    }

    private AdapterView.OnItemClickListener onTestFunctionClicked = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            final String functionName = ((TextView) view).getText().toString();
            if ((functionName == null) || (functionName.isEmpty()))
                return;
            DisableUI();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        TestFunction fun = new TestFunction();
                        fun.ctx = activity;
                        Method m = TestFunction.class.getDeclaredMethod(functionName, Pointer.class);
                        m.invoke(fun, h);
                    } catch (Throwable tr) {
                        tr.printStackTrace();
                    }
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            RefreshUI();
                        }
                    });
                }
            }).start();
        }
    };

    private void EnumCom() {
        cbxListCOMPort.setText("");
        cbxListCOMPort.clear();
        String[] devicePaths = printerlibs_caysnpos.CaysnPos_EnumCom_Helper.CaysnPos_EnumComA();
        if (devicePaths != null) {
            for (int i = 0; i < devicePaths.length; ++i) {
                String name = devicePaths[i];
                cbxListCOMPort.addString(name);
                String text = cbxListCOMPort.getText();
                if (text.trim().equals("")) {
                    text = name;
                    cbxListCOMPort.setText(text);
                }
            }
        }
    }

    private void EnumUsb() {
        cbxListUSB.setText("");
        cbxListUSB.clear();
        String[] devicePaths = printerlibs_caysnpos.CaysnPos_EnumUsbVidPid_Helper.CaysnPos_EnumUsbVidPidA();
        if (devicePaths != null) {
            for (int i = 0; i < devicePaths.length; ++i) {
                String name = devicePaths[i];
                cbxListUSB.addString(name);
                String text = cbxListUSB.getText();
                if (text.trim().equals("")) {
                    text = name;
                    cbxListUSB.setText(text);
                }
            }
        }
    }

    boolean inNetEnum = false;

    private void EnumNet() {
        if (inNetEnum)
            return;
        inNetEnum = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                IntByReference cancel = new IntByReference(0);
                printerlibs_caysnpos.on_netprinter_discovered_a_callback callback = new printerlibs_caysnpos.on_netprinter_discovered_a_callback() {
                    @Override
                    public void on_netprinter_discovered_a(String local_ip, String disconvered_mac, final String disconvered_ip, String discovered_name, Pointer private_data) {
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (!cbxListNET.getData().contains(disconvered_ip))
                                    cbxListNET.addString(disconvered_ip);
                                if (cbxListNET.getText().trim().equals("")) {
                                    cbxListNET.setText(disconvered_ip);
                                }
                            }
                        });
                    }
                };
                printerlibs_caysnpos.INSTANCE.CaysnPos_EnumNetPrinterA(3000, cancel, callback, null);
                inNetEnum = false;
            }
        }).start();
    }

    boolean inBtEnum = false;

    private void EnumBt() {
        if (inBtEnum)
            return;
        inBtEnum = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                IntByReference cancel = new IntByReference(0);
                printerlibs_caysnpos.on_btdevice_discovered_a_callback callback = new printerlibs_caysnpos.on_btdevice_discovered_a_callback() {
                    @Override
                    public void on_btdevice_discovered_a(String device_name, final String device_address, Pointer private_data) {
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (!cbxListBT2.getData().contains(device_address))
                                    cbxListBT2.addString(device_address);
                                if (cbxListBT2.getText().trim().equals("")) {
                                    cbxListBT2.setText(device_address);
                                }
                            }
                        });
                    }
                };
                printerlibs_caysnpos.INSTANCE.CaysnPos_EnumBtDeviceA(12000, cancel, callback, null);
                inBtEnum = false;
            }
        }).start();
    }

    boolean inBleEnum = false;

    private void EnumBle() {
        if (inBleEnum)
            return;
        inBleEnum = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                IntByReference cancel = new IntByReference(0);
                printerlibs_caysnpos.on_btdevice_discovered_a_callback callback = new printerlibs_caysnpos.on_btdevice_discovered_a_callback() {
                    @Override
                    public void on_btdevice_discovered_a(String device_name, final String device_address, Pointer private_data) {
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (!cbxListBT4.getData().contains(device_address))
                                    cbxListBT4.addString(device_address);
                                if (cbxListBT4.getText().trim().equals("")) {
                                    cbxListBT4.setText(device_address);
                                }
                            }
                        });
                    }
                };
                printerlibs_caysnpos.INSTANCE.CaysnPos_EnumBleDeviceA(20000, cancel, callback, null);
                inBleEnum = false;
            }
        }).start();
    }

    private void EnumPort() {
        EnumCom();
        EnumUsb();
        EnumNet();
        EnumBt();
        EnumBle();
    }

    private void OpenPort() {
        DisableUI();
        final boolean rbBT2Checked = rbBT2.isChecked();
        final boolean rbBT4Checked = rbBT4.isChecked();
        final boolean rbNETChecked = rbNET.isChecked();
        final boolean rbUSBChecked = rbUSB.isChecked();
        final boolean rbCOMChecked = rbCOM.isChecked();
        final boolean chkListenBT2Checked = chkListenBT2.isChecked();
        final String strBT2Address = cbxListBT2.getText();
        final String strBT4Address = cbxListBT4.getText();
        final String strNETAddress = cbxListNET.getText();
        final String strUSBPort = cbxListUSB.getText();
        final String strCOMPort = cbxListCOMPort.getText();
        final int nComBaudrate = Integer.parseInt(cbxListCOMBaud.getText());
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (rbBT2Checked) {
                    if (chkListenBT2Checked) {
                        final byte[] listenedAddress = new byte[18];
                        h = printerlibs_caysnpos.INSTANCE.CaysnPos_OpenBT2ByListenA(30000, listenedAddress);
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                cbxListBT2.setText(new String(listenedAddress));
                            }
                        });
                    } else {
                        h = printerlibs_caysnpos.INSTANCE.CaysnPos_OpenBT2ByConnectA(strBT2Address);
                    }
                } else if (rbBT4Checked) {
                    h = printerlibs_caysnpos.INSTANCE.CaysnPos_OpenBT4ByConnectA(strBT4Address);
                } else if (rbNETChecked) {
                    h = printerlibs_caysnpos.INSTANCE.CaysnPos_OpenTcpA(strNETAddress, (short) 9100, 5000);
                } else if (rbUSBChecked) {
                    h = printerlibs_caysnpos.INSTANCE.CaysnPos_OpenUsbVidPidStringA(strUSBPort);
                } else if (rbCOMChecked) {
                    h = printerlibs_caysnpos.INSTANCE.CaysnPos_OpenComA(strCOMPort, nComBaudrate, 8, 0, 0, 0);
                }
                printerlibs_caysnpos.INSTANCE.CaysnPos_SetClosedEvent(h, closed_callback, Pointer.NULL);
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        RefreshUI();
                    }
                });
            }
        }).start();
    }

    private void ClosePort() {
        if (h != Pointer.NULL) {
            printerlibs_caysnpos.INSTANCE.CaysnPos_Close(h);
            h = Pointer.NULL;
        }
        RefreshUI();
    }

    private void DisableUI() {
        rbBT2.setEnabled(false);
        rbBT4.setEnabled(false);
        rbNET.setEnabled(false);
        rbUSB.setEnabled(false);
        rbCOM.setEnabled(false);
        chkListenBT2.setEnabled(false);
        cbxListBT2.setEnabled(false);
        cbxListBT4.setEnabled(false);
        cbxListNET.setEnabled(false);
        cbxListUSB.setEnabled(false);
        cbxListCOMPort.setEnabled(false);
        cbxListCOMBaud.setEnabled(false);
        btnEnumPort.setEnabled(false);
        btnOpenPort.setEnabled(false);
        btnClosePort.setEnabled(false);
        listViewTestFunction.setEnabled(false);
    }

    private void RefreshUI() {
        rbBT2.setEnabled(h == Pointer.NULL);
        rbBT4.setEnabled(h == Pointer.NULL);
        rbNET.setEnabled(h == Pointer.NULL);
        rbUSB.setEnabled(h == Pointer.NULL);
        rbCOM.setEnabled(h == Pointer.NULL);
        chkListenBT2.setEnabled(h == Pointer.NULL);
        cbxListBT2.setEnabled(h == Pointer.NULL);
        cbxListBT4.setEnabled(h == Pointer.NULL);
        cbxListNET.setEnabled(h == Pointer.NULL);
        cbxListUSB.setEnabled(h == Pointer.NULL);
        cbxListCOMPort.setEnabled(h == Pointer.NULL);
        cbxListCOMBaud.setEnabled(h == Pointer.NULL);
        btnEnumPort.setEnabled(h == Pointer.NULL);
        btnOpenPort.setEnabled(h == Pointer.NULL);
        btnClosePort.setEnabled(h != Pointer.NULL);
        listViewTestFunction.setEnabled(h != Pointer.NULL);

        int visibility = (h == Pointer.NULL) ? View.VISIBLE : View.GONE;
        if (!rbBT2.isChecked()) {
            rbBT2.setVisibility(visibility);
            chkListenBT2.setVisibility(visibility);
            cbxListBT2.setVisibility(visibility);
        }
        if (!rbBT4.isChecked()) {
            rbBT4.setVisibility(visibility);
            cbxListBT4.setVisibility(visibility);
        }
        if (!rbNET.isChecked()) {
            rbNET.setVisibility(visibility);
            cbxListNET.setVisibility(visibility);
        }
        if (!rbUSB.isChecked()) {
            rbUSB.setVisibility(visibility);
            cbxListUSB.setVisibility(visibility);
        }
        if (!rbCOM.isChecked()) {
            rbCOM.setVisibility(visibility);
            cbxListCOMPort.setVisibility(visibility);
            cbxListCOMBaud.setVisibility(visibility);
        }
    }
}

class GRadioGroup {
    List<RadioButton> radios = new ArrayList<>();

    public GRadioGroup(RadioButton... radios) {
        super();
        for (RadioButton rb : radios) {
            this.radios.add(rb);
            rb.setOnClickListener(onClick);
        }
    }

    public GRadioGroup(View activity, int... radiosIDs) {
        super();
        for (int radioButtonID : radiosIDs) {
            RadioButton rb = (RadioButton) activity.findViewById(radioButtonID);
            if (rb != null) {
                this.radios.add(rb);
                rb.setOnClickListener(onClick);
            }
        }
    }

    OnClickListener onClick = new OnClickListener() {
        @Override
        public void onClick(View v) {
            //let's deselect all radios in group
            for (RadioButton rb : radios) {
                ViewParent p = rb.getParent();
                if (p.getClass().equals(RadioGroup.class)) {
                    //if RadioButton belongs to RadioGroup,
                    // then deselect all radios in it
                    RadioGroup rg = (RadioGroup) p;
                    rg.clearCheck();
                } else {
                    //if RadioButton DOES NOT belong to RadioGroup,
                    //just deselect it
                    rb.setChecked(false);
                }
            }
            //now let's select currently clicked RadioButton
            if (v.getClass().equals(RadioButton.class)) {
                RadioButton rb = (RadioButton) v;
                rb.setChecked(true);
            }
        }
    };
}

class TestFunction {

    public static String[] testFunctionOrderedList = new String[]{
            "onTest_SampleTicket_58MM_1",
            "onTest_SampleTicket_80MM_1",

            "onTest_CaysnPos_QueryPrinterBufferEmpty",
            "onTest_CaysnPos_QueryPrinterStatus",
            "onTest_CaysnPos_QueryPrintResult",
            "onTest_CaysnPos_KickOutDrawer",
            "onTest_CaysnPos_Beep",
            "onTest_CaysnPos_FeedAndHalfCutPaper",
            "onTest_CaysnPos_FullCutPaper",
            "onTest_CaysnPos_HalfCutPaper",
            "onTest_CaysnPos_ResetPrinter",
            "onTest_CaysnPos_SetPrinter",
            "onTest_CaysnPos_SetPrintSpeed",
            "onTest_CaysnPos_SetPrintDensity_Light",
            "onTest_CaysnPos_SetPrintDensity_Normal",
            "onTest_CaysnPos_SetPrintDensity_Dark",
            "onTest_CaysnPos_SetPrintHeatPara_HeatTimeShort",
            "onTest_CaysnPos_SetPrintHeatPara_HeatTimeLong",
            "onTest_CaysnPos_PrintSelfTestPage",
            "onTest_CaysnPos_SetMovementUnit",
            "onTest_CaysnPos_SetPrintAreaLeftMargin",
            "onTest_CaysnPos_SetPrintAreaWidth",
            "onTest_CaysnPos_SetPrintPosition",
            "onTest_CaysnPos_SetAlignment",
            "onTest_CaysnPos_Feed",
            "onTest_CaysnPos_PrintTextA",
            "onTest_CaysnPos_PrintTextInUTF8W",
            "onTest_CaysnPos_PrintTextInGBKW",
            "onTest_CaysnPos_PrintTextInBIG5W",
            "onTest_CaysnPos_PrintTextInShiftJISW",
            "onTest_CaysnPos_PrintTextInEUCKRW",
            "onTest_CaysnPos_SetTextScale",
            "onTest_CaysnPos_SetAsciiTextFontType",
            "onTest_CaysnPos_SetTextBold",
            "onTest_CaysnPos_SetTextUnderline",
            "onTest_CaysnPos_SetTextUpsideDown",
            "onTest_CaysnPos_SetTextWhiteOnBlack",
            "onTest_CaysnPos_SetTextRotate",
            "onTest_CaysnPos_SetTextLineHeight",
            "onTest_CaysnPos_SetAsciiTextCharRightSpacing",
            "onTest_CaysnPos_SetKanjiTextCharSpacing",
            "onTest_CaysnPos_SetSingleByteMode",
            "onTest_CaysnPos_SetCharacterSet",
            "onTest_CaysnPos_SetCharacterCodepage",
            "onTest_CaysnPos_SetMultiByteMode",
            "onTest_CaysnPos_SetMultiByteEncoding",
            "onTest_CaysnPos_SetUserCharacterPatternFromBitmap",
            "onTest_CaysnPos_SetUserKanjiPatternFromBitmap",
            "onTest_CaysnPos_PrintBarcode",
            "onTest_CaysnPos_PrintQRCode",
            "onTest_CaysnPos_PrintQRCodeUseEpsonCmd",
            "onTest_CaysnPos_PrintDoubleQRCode",
            "onTest_CaysnPos_PrintPDF417BarcodeUseEpsonCmd",

            "onTest_CaysnPos_PrintRasterImageFromBitmap",
            "onTest_CaysnPos_PrintRasterImageWithCompressFromBitmap",
            "onTest_CaysnPos_FillDotImageToCurrentLineFromBitmap",
            "onTest_CaysnPos_PrintDotImageSpecifyHorizontalPositionFromBitmap",

            "onTest_CaysnPos_PrintHorizontalLine",
            "onTest_CaysnPos_PrintHorizontalLineSpecifyThickness",
            "onTest_CaysnPos_PrintMultipleHorizontalLinesAtOneRow",
    };

    public Activity ctx = null;

    /**
     * 打印小票例子-58MM
     * @param h
     */
    void onTest_SampleTicket_58MM_1(Pointer h)
    {
        int paperWidth = 384;

        printerlibs_caysnpos.INSTANCE.CaysnPos_ResetPrinter(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "123xxstreet,xxxcity,xxxxstate\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAlignment(h, printerlibs_caysnpos.PosAlignment_Right);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "TEL 9999-99-9999  C#2\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAlignment(h, printerlibs_caysnpos.PosAlignment_HCenter);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "yyyy-MM-dd HH:mm:ss");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);

        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "apples");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, paperWidth - 12*6);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "$10.00");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "grapes");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, paperWidth - 12*6);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "$20.00");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "bananas");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, paperWidth - 12*6);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "$30.00");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "lemons");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, paperWidth - 12*6);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "$40.00");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "oranges");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, paperWidth - 12*7);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "$100.00");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "Before adding tax");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, paperWidth - 12*7);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "$200.00");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "tax 5.0%");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, paperWidth - 12*6);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "$10.00");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        String line = "";
        for (int i = 0; i < paperWidth / 12; ++i)
            line += " ";
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextUnderline(h, printerlibs_caysnpos.TextUnderline_Two);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, line);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextUnderline(h, printerlibs_caysnpos.TextUnderline_None);
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 1, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "total");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, paperWidth - 12*2*7);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "$190.00");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 0, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "Customer's payment");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, paperWidth - 12*7);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "$200.00");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "Change");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, paperWidth - 12*6);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "$10.00");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);

        printerlibs_caysnpos.INSTANCE.CaysnPos_SetBarcodeHeight(h, 60);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetBarcodeUnitWidth(h, 3);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetBarcodeReadableTextPosition(h, printerlibs_caysnpos.BarcodeReadableTextPosition_BelowBarcode);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeA(h, printerlibs_caysnpos.PosBarcodeType_UPCA, "12345678901");

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_Beep(h, 1, 500);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 打印小票例子-80MM
     * @param h
     */
    void onTest_SampleTicket_80MM_1(Pointer h)
    {
        int[] nLineStartPos = { 0, 201, 401};
        int[] nLineEndPos = { 200, 400, 575};

        {
            //初始化打印
            printerlibs_caysnpos.INSTANCE.CaysnPos_ResetPrinter(h);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_UTF8);
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 2);
        }

        {
            //打印一条2倍高横线
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
        }

        {
            //设置距离上部2行距离
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 2);
            //设置后面文本打印位置
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetAlignment(h, printerlibs_caysnpos.PosAlignment_Right);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("服务台\r\n"));
        }

        {
            //设置距离上部2行距离
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 2);

            int nStartPos = 0;
            int nEndPos = 120;
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintHorizontalLineSpecifyThickness(h, nStartPos, nEndPos, 3);
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedDot(h, 10);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetAlignment(h, printerlibs_caysnpos.PosAlignment_Left);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextBold(h, 1);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 1, 1);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 12);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("圆桌"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedDot(h, 0);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 0, 0);
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedDot(h, 10);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintHorizontalLineSpecifyThickness(h, nStartPos, nEndPos, 3);
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextBold(h, 0);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("麻辣香锅（上梅林店）\r\n2018年2月7日15:51:00\r\n\r\n"));
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetAlignment(h, printerlibs_caysnpos.PosAlignment_HCenter);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 1, 1);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("\r\n15-D-一楼-大厅-散座\r\n"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetAlignment(h, printerlibs_caysnpos.PosAlignment_Left);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 0, 0);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("\r\n扫码点餐订单\r\n店内用餐\r\n7人\r\n"));
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 0);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("\r\n热菜类\r\n"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 80);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("鱼香肉丝"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 200);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("1"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 480);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("¥23.50\r\n"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 80);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("麻辣鸡丝"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 200);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("1"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 480);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("¥23.50\r\n"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 0);

            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("凉菜类\r\n"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 80);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("凉拌腐竹"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 200);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("1"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 480);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("¥23.50\r\n"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 80);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("糖醋花生"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 200);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("1"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 480);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("¥23.50\r\n"));
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedDot(h, 30);
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 80);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("消毒餐具"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 200);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("7"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 480);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("¥14.00\r\n"));
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 2);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 0);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("在线支付"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 480);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("¥114.00\r\n"));
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("备注\r\n"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintAreaLeftMargin(h, 80);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("所有菜都不要放葱，口味要微辣。百事可乐不要加冰。上菜快点，太慢了！！\r\n\r\n"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintAreaLeftMargin(h, 0);
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetAlignment(h, printerlibs_caysnpos.PosAlignment_HCenter);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintQRCodeW(h, 0, printerlibs_caysnpos.QRCodeECC_L, new WString("麻辣香锅"));
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("\r\n用心服务每一天\r\n40008083030\r\n\r\n"));
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, nLineStartPos.length, nLineStartPos, nLineEndPos);
        }

        {
            printerlibs_caysnpos.INSTANCE.CaysnPos_Beep(h, 3, 300);
            int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedAndHalfCutPaper(h);
            if (result == 0)
                TestUtils.showMessageOnUiThread(ctx, "Write failed");
        }
    }

    /**
     * 查看打印缓存状态
     * @param h
     */
    void onTest_CaysnPos_QueryPrinterBufferEmpty(Pointer h) {
        String msg;

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_QueryPrinterBufferEmpty(h, 3000);
        switch (result) {
            case printerlibs_caysnpos.PL_QUERYBUFFER_EMTPY:
                msg = "Empty";
                break;
            case printerlibs_caysnpos.PL_QUERYBUFFER_FAILED_PORT_CLOSED:
                msg = "Port closed";
                break;
            case printerlibs_caysnpos.PL_QUERYBUFFER_FAILED_PORT_WRITEFAILED:
                msg = "Write failed";
                break;
            case printerlibs_caysnpos.PL_QUERYBUFFER_FAILED_PORT_READFAILED:
                msg = "Read failed";
                break;
            case printerlibs_caysnpos.PL_QUERYBUFFER_NOT_EMPTY:
            default:
                msg = "Not empty";
                break;
        }

        TestUtils.showMessageOnUiThread(ctx, msg);
    }

    /**
     * 查看打印机状态
     * @param h
     */
    void onTest_CaysnPos_QueryPrinterStatus(Pointer h) {
        String msg = "";

        int status = printerlibs_caysnpos.INSTANCE.CaysnPos_QueryPrinterStatus(h, 3000);
        if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_QUERYFAILED(status)) {
            msg += "Query Failed\r\n";
        } else {
            msg += String.format("Query Success %02X %02X %02X %02X\r\n",
                    ((status & 0xFFL) >> 0),
                    ((status & 0xFF00L) >> 8),
                    ((status & 0xFF0000L) >> 16),
                    ((status & 0xFF000000L) >> 24));
            if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_DRAWER_OPENED(status))
                msg += "Drawer opened\r\n";
            if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_OFFLINE(status))
                msg += "Printer offline\r\n";
            if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_COVERUP(status))
                msg += "Cover up\r\n";
            if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_FEED_PRESSED(status))
                msg += "Feed key pressed\r\n";
            if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_NOPAPER(status))
                msg += "No paper\r\n";
            if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_ERROR_OCCURED(status))
                msg += "Error occured\r\n";
            if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_CUTTER_ERROR(status))
                msg += "Cutter error\r\n";
            if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_UNRECOVERABLE_ERROR(status))
                msg += "Unrecoverable error\r\n";
            if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_DEGREE_OR_VOLTAGE_OVERRANGE(status))
                msg += "Degree or voltage overrange\r\n";
            if (printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_PAPER_NEAREND(status))
                msg += "Paper near end\r\n";
            if (!printerlibs_caysnpos.PL_PRINTERSTATUS_Helper.PL_PRINTERSTATUS_PAPER_TAKEOUT(status))
                msg += "Paper not takeout\r\n";
        }

        TestUtils.showMessageOnUiThread(ctx, msg);
    }

    /**
     * 查询打印结果
     * @param h
     */
    void onTest_CaysnPos_QueryPrintResult(Pointer h) {
        String msg;

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_QueryPrintResult(h, 3000);
        switch (result) {
            case printerlibs_caysnpos.PL_PRINTRESULT_SUCCESS:
                msg = "Print success";
                break;
            case printerlibs_caysnpos.PL_PRINTRESULT_PORT_CLOSED:
                msg = "Port closed";
                break;
            case printerlibs_caysnpos.PL_PRINTRESULT_PORT_WRITEFAILED:
                msg = "Write failed";
                break;
            case printerlibs_caysnpos.PL_PRINTRESULT_PORT_READFAILED:
                msg = "Read failed";
                break;
            case printerlibs_caysnpos.PL_PRINTRESULT_PRINTER_OFFLINE:
                msg = "Printer offline";
                break;
            case printerlibs_caysnpos.PL_PRINTRESULT_PRINTER_NOPAPER:
                msg = "No paper";
                break;
            case printerlibs_caysnpos.PL_PRINTRESULT_OTHER_RERROR:
            default:
                msg = "Print failed";
                break;
        }

        TestUtils.showMessageOnUiThread(ctx, msg);
    }

    /**
     * 开启钱箱
     * @param h
     */
    void onTest_CaysnPos_KickOutDrawer(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_KickOutDrawer(h, 0, 100, 100);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_KickOutDrawer(h, 1, 100, 100);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    void onTest_CaysnPos_Beep(Pointer h) {
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_Beep(h, 3, 300);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    void onTest_CaysnPos_FeedAndHalfCutPaper(Pointer h) {
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedAndHalfCutPaper(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    void onTest_CaysnPos_FullCutPaper(Pointer h) {
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FullCutPaper(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    void onTest_CaysnPos_HalfCutPaper(Pointer h) {
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_HalfCutPaper(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 重置打印机
     * @param h
     */
    void onTest_CaysnPos_ResetPrinter(Pointer h) {
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_ResetPrinter(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    void onTest_CaysnPos_SetPrinter(Pointer h) {
        byte[] nDensity = new byte[]{2};
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrinter(h, 's', nDensity, 1);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置打印速度
     * @param h
     */
    void onTest_CaysnPos_SetPrintSpeed(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintSpeed(h, 20);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintSelfTestPage(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    void onTest_CaysnPos_SetPrintDensity_Light(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintDensity(h, 0);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintSelfTestPage(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置打印密度-正常
     * @param h
     */
    void onTest_CaysnPos_SetPrintDensity_Normal(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintDensity(h, 1);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintSelfTestPage(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置打印密度-暗
     * @param h
     */
    void onTest_CaysnPos_SetPrintDensity_Dark(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintDensity(h, 2);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintSelfTestPage(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    void onTest_CaysnPos_SetPrintHeatPara_HeatTimeShort(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintHeatPara(h, 80, 800, 200);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintSelfTestPage(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置打印加热时间
     * @param h
     */
    void onTest_CaysnPos_SetPrintHeatPara_HeatTimeLong(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintHeatPara(h, 80, 1200, 200);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintSelfTestPage(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 打印自检页
     * @param h
     */
    void onTest_CaysnPos_PrintSelfTestPage(Pointer h) {
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintSelfTestPage(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置移动单元
     * @param h
     */
    void onTest_CaysnPos_SetMovementUnit(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMovementUnit(h, 100, 100);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextCharRightSpacing(h, 10);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "1234567890\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMovementUnit(h, 200, 200);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextCharRightSpacing(h, 10);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "1234567890\r\n");
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextCharRightSpacing(h, 0);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置打印区域左边距
     * @param h
     */
    void onTest_CaysnPos_SetPrintAreaLeftMargin(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintAreaLeftMargin(h, 96);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintAreaWidth(h, 384);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "1234567890123456789012345678901234567890\r\n");
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_ResetPrinter(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置打印区域宽度
     * @param h
     */
    void onTest_CaysnPos_SetPrintAreaWidth(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetPrintAreaWidth(h, 384);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "1234567890123456789012345678901234567890\r\n");
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_ResetPrinter(h);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置打印位置
     * @param h
     */
    void onTest_CaysnPos_SetPrintPosition(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "12345678901234567890\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, 24);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "1234567890");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalRelativePrintPosition(h, 24);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "1234567890\r\n");
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置对齐方式
     * @param h
     */
    void onTest_CaysnPos_SetAlignment(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAlignment(h, printerlibs_caysnpos.PosAlignment_Right);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "12345678901234567890\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAlignment(h, printerlibs_caysnpos.PosAlignment_HCenter);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "12345678901234567890\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAlignment(h, printerlibs_caysnpos.PosAlignment_Left);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "12345678901234567890\r\n");
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 填充打印
     * @param h
     */
    void onTest_CaysnPos_Feed(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "12345678901234567890");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 4);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "12345678901234567890");
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedDot(h, 100);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 打印文本
     * @param h
     */
    void onTest_CaysnPos_PrintTextA(Pointer h) {
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "12345678901234567890\r\n");
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }
    /**
     * 用UTF8W打印文本
     * @param h
     */
    void onTest_CaysnPos_PrintTextInUTF8W(Pointer h) {
        WString str = new WString(
                "1234567890\r\n" +
                        "abcdefghijklmnopqrstuvwxyz\r\n" +
                        "ΑΒΓΔΕΖΗΘΙΚ∧ΜΝΞΟ∏Ρ∑ΤΥΦΧΨΩ\r\n" +
                        "αβγδεζηθικλμνξοπρστυφχψω\r\n" +
                        "你好，欢迎使用！\r\n" +
                        "你號，歡迎使用！\r\n" +
                        "梦を见る事が出来なければ\r\n未来を変える事は出来ません\r\n" +
                        "왕관을 쓰려는자\r\n그 무게를 견뎌라\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_UTF8);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, str);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }
    /**
     * 用GBKW打印文本
     * @param h
     */
    void onTest_CaysnPos_PrintTextInGBKW(Pointer h) {
        WString str = new WString("1234567890\r\nabcdefghijklmnopqrstuvwxyz\r\n你好，欢迎使用！\r\n你號，歡迎使用！\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_GBK);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInGBKW(h, str);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 用BIG5W打印文本
     * @param h
     */
    void onTest_CaysnPos_PrintTextInBIG5W(Pointer h) {
        WString str = new WString("1234567890\r\nabcdefghijklmnopqrstuvwxyz\r\n你號，歡迎使用！\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_BIG5);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInBIG5W(h, str);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 用日文打印文本
     * @param h
     */
    void onTest_CaysnPos_PrintTextInShiftJISW(Pointer h) {
        WString str = new WString(
                "1234567890\r\n" +
                        "abcdefghijklmnopqrstuvwxyz\r\n" +
                        "こんにちは\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_ShiftJIS);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInShiftJISW(h, str);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 用韩文打印文本
     * @param h
     */
    void onTest_CaysnPos_PrintTextInEUCKRW(Pointer h) {
        WString str = new WString(
                "1234567890\r\n" +
                        "abcdefghijklmnopqrstuvwxyz\r\n" +
                        "왕관을 쓰려는자\r\n" +
                        "그 무게를 견뎌라\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_EUCKR);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInEUCKRW(h, str);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置文本缩放
     * @param h
     */
    void onTest_CaysnPos_SetTextScale(Pointer h) {
        int nPosition = 0;
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, nPosition);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 0, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "a");
        nPosition += 12;
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, nPosition);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 1, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "a");
        nPosition += 12 * 2;
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, nPosition);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 2, 2);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "a");
        nPosition += 12 * 3;
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, nPosition);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 3, 3);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "a");
        nPosition += 12 * 4;
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, nPosition);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 4, 4);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "a");
        nPosition += 12 * 5;
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, nPosition);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 5, 5);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "a");
        nPosition += 12 * 6;
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, nPosition);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 6, 6);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "a");
        nPosition += 12 * 7;
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetHorizontalAbsolutePrintPosition(h, nPosition);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 7, 7);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "a");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextScale(h, 0, 0);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置Ascii文本字体类型
     * @param h
     */
    void onTest_CaysnPos_SetAsciiTextFontType(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextFontType(h, printerlibs_caysnpos.AsciiTextFontType_A);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "FontA\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextFontType(h, printerlibs_caysnpos.AsciiTextFontType_B);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "FontB\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextFontType(h, printerlibs_caysnpos.AsciiTextFontType_C);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "FontC\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextFontType(h, printerlibs_caysnpos.AsciiTextFontType_D);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "FontD\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextFontType(h, printerlibs_caysnpos.AsciiTextFontType_E);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "FontE\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextFontType(h, printerlibs_caysnpos.AsciiTextFontType_A);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置文本粗体
     * @param h
     */
    void onTest_CaysnPos_SetTextBold(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextBold(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_UTF8);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("粗体 Bold\r\n"));
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextBold(h, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "Normal\r\n");
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置文本下划线
     * @param h
     */
    void onTest_CaysnPos_SetTextUnderline(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_UTF8);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextUnderline(h, printerlibs_caysnpos.TextUnderline_Two);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("下划线2点 Underline2\r\n"));
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextUnderline(h, printerlibs_caysnpos.TextUnderline_One);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("下划线1点 Underline2\r\n"));
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextUnderline(h, printerlibs_caysnpos.TextUnderline_None);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("无下划线 No Underline\r\n"));
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置文本上下倒置
     * @param h
     */
    void onTest_CaysnPos_SetTextUpsideDown(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_UTF8);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextUpsideDown(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("上下倒置 UpsideDown\r\n"));
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextUpsideDown(h, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "Normal\r\n");
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置文本黑白反显
     * @param h
     */
    void onTest_CaysnPos_SetTextWhiteOnBlack(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_UTF8);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextWhiteOnBlack(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("黑白反显 WhiteOnBlack\r\n"));
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextWhiteOnBlack(h, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "Normal\r\n");
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置文本旋转
     * @param h
     */
    void onTest_CaysnPos_SetTextRotate(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_UTF8);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextRotate(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, new WString("文字旋转打印 TextRotate\r\n"));
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextRotate(h, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "Normal\r\n");
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置文本行高
     * @param h
     */
    void onTest_CaysnPos_SetTextLineHeight(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextLineHeight(h, 100);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "LineHeight 100\r\nLineHeight 100\r\nLineHeight 100\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetTextLineHeight(h, 32);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "LineHeight 32\r\nLineHeight 32\r\nLineHeight 32\r\n");
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置Ascii文本字符右间距
     * @param h
     */
    void onTest_CaysnPos_SetAsciiTextCharRightSpacing(Pointer h) {
        WString str = new WString("Hello你好\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_UTF8);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextCharRightSpacing(h, 2);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, str);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetAsciiTextCharRightSpacing(h, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, str);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置汉字文本字符间距
     * @param h
     */
    void onTest_CaysnPos_SetKanjiTextCharSpacing(Pointer h) {
        WString str = new WString("Hello你好\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_UTF8);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetKanjiTextCharSpacing(h, 2, 2);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, str);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetKanjiTextCharSpacing(h, 0, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextInUTF8W(h, str);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置单字节模式
     * @param h
     */
    void onTest_CaysnPos_SetSingleByteMode(Pointer h) {
        byte[] data = new byte[]{(byte) 0xc4, (byte) 0xe3, (byte) 0xba, (byte) 0xc3};
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetSingleByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetCharacterSet(h, printerlibs_caysnpos.CharacterSet_CHINA);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetCharacterCodepage(h, printerlibs_caysnpos.CharacterCodepage_CP437);
        printerlibs_caysnpos.INSTANCE.CaysnPos_Write(h, data, data.length, 1000);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置字符集
     * @param h
     */
    void onTest_CaysnPos_SetCharacterSet(Pointer h) {
        byte[] chs = new byte[0x60];
        for (int i = 0; i < 0x60; ++i) {
            chs[i] = (byte) (i + 0x20);
        }
        int[] characterSetCode = new int[]{
                printerlibs_caysnpos.CharacterSet_USA,
                printerlibs_caysnpos.CharacterSet_FRANCE,
                printerlibs_caysnpos.CharacterSet_GERMANY,
                printerlibs_caysnpos.CharacterSet_UK,
                printerlibs_caysnpos.CharacterSet_DENMARK_I,
                printerlibs_caysnpos.CharacterSet_SWEDEN,
                printerlibs_caysnpos.CharacterSet_ITALY,
                printerlibs_caysnpos.CharacterSet_SPAIN_I,
                printerlibs_caysnpos.CharacterSet_JAPAN,
                printerlibs_caysnpos.CharacterSet_NORWAY,
                printerlibs_caysnpos.CharacterSet_DENMARK_II,
                printerlibs_caysnpos.CharacterSet_SPAIN_II,
                printerlibs_caysnpos.CharacterSet_LATIN,
                printerlibs_caysnpos.CharacterSet_KOREA,
                printerlibs_caysnpos.CharacterSet_SLOVENIA,
                printerlibs_caysnpos.CharacterSet_CHINA
        };
        String[] characterSetName = new String[]{
                "USA",
                "FRANCE",
                "GERMANY",
                "UK",
                "DENMARK_I",
                "SWEDEN",
                "ITALY",
                "SPAIN_I",
                "JAPAN",
                "NORWAY",
                "DENMARK_II",
                "SPAIN_II",
                "LATIN",
                "KOREA",
                "SLOVENIA",
                "CHINA",
        };

        printerlibs_caysnpos.INSTANCE.CaysnPos_SetSingleByteMode(h);
        for (int i = 0; i < characterSetCode.length; ++i) {
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetCharacterSet(h, characterSetCode[i]);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, characterSetName[i]);
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
            printerlibs_caysnpos.INSTANCE.CaysnPos_Write(h, chs, chs.length, 3000);
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 2);
        }
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置字符代码页
     * @param h
     */
    void onTest_CaysnPos_SetCharacterCodepage(Pointer h) {
        byte[] chs = new byte[0x80];
        for (int i = 0; i < 0x80; ++i) {
            chs[i] = (byte) (i + 0x80);
        }
        int[] characterCodepageCode = new int[]{
                printerlibs_caysnpos.CharacterCodepage_CP437,
                printerlibs_caysnpos.CharacterCodepage_KATAKANA,
                printerlibs_caysnpos.CharacterCodepage_CP850,
                printerlibs_caysnpos.CharacterCodepage_CP860,
                printerlibs_caysnpos.CharacterCodepage_CP863,
                printerlibs_caysnpos.CharacterCodepage_CP865,
                printerlibs_caysnpos.CharacterCodepage_WCP1251,
                printerlibs_caysnpos.CharacterCodepage_CP866,
                printerlibs_caysnpos.CharacterCodepage_MIK,
                printerlibs_caysnpos.CharacterCodepage_CP755,
                printerlibs_caysnpos.CharacterCodepage_IRAN,
                printerlibs_caysnpos.CharacterCodepage_CP862,
                printerlibs_caysnpos.CharacterCodepage_WCP1252,
                printerlibs_caysnpos.CharacterCodepage_WCP1253,
                printerlibs_caysnpos.CharacterCodepage_CP852,
                printerlibs_caysnpos.CharacterCodepage_CP858,
                printerlibs_caysnpos.CharacterCodepage_IRAN_II,
                printerlibs_caysnpos.CharacterCodepage_LATVIAN,
                printerlibs_caysnpos.CharacterCodepage_CP864,
                printerlibs_caysnpos.CharacterCodepage_ISO_8859_1,
                printerlibs_caysnpos.CharacterCodepage_CP737,
                printerlibs_caysnpos.CharacterCodepage_WCP1257,
                printerlibs_caysnpos.CharacterCodepage_THAI,
                printerlibs_caysnpos.CharacterCodepage_CP720,
                printerlibs_caysnpos.CharacterCodepage_CP855,
                printerlibs_caysnpos.CharacterCodepage_CP857,
                printerlibs_caysnpos.CharacterCodepage_WCP1250,
                printerlibs_caysnpos.CharacterCodepage_CP775,
                printerlibs_caysnpos.CharacterCodepage_WCP1254,
                printerlibs_caysnpos.CharacterCodepage_WCP1255,
                printerlibs_caysnpos.CharacterCodepage_WCP1256,
                printerlibs_caysnpos.CharacterCodepage_WCP1258,
                printerlibs_caysnpos.CharacterCodepage_ISO_8859_2,
                printerlibs_caysnpos.CharacterCodepage_ISO_8859_3,
                printerlibs_caysnpos.CharacterCodepage_ISO_8859_4,
                printerlibs_caysnpos.CharacterCodepage_ISO_8859_5,
                printerlibs_caysnpos.CharacterCodepage_ISO_8859_6,
                printerlibs_caysnpos.CharacterCodepage_ISO_8859_7,
                printerlibs_caysnpos.CharacterCodepage_ISO_8859_8,
                printerlibs_caysnpos.CharacterCodepage_ISO_8859_9,
                printerlibs_caysnpos.CharacterCodepage_ISO_8859_15,
                printerlibs_caysnpos.CharacterCodepage_THAI_2,
                printerlibs_caysnpos.CharacterCodepage_CP856,
                printerlibs_caysnpos.CharacterCodepage_CP874,
                printerlibs_caysnpos.CharacterCodepage_TCVN3,
        };
        String[] characterCodepageName = new String[]{
                "CP437",
                "KATAKANA",
                "CP850",
                "CP860",
                "CP863",
                "CP865",
                "WCP1251",
                "CP866",
                "MIK",
                "CP755",
                "IRAN",
                "CP862",
                "WCP1252",
                "WCP1253",
                "CP852",
                "CP858",
                "IRAN_II",
                "LATVIAN",
                "CP864",
                "ISO_8859_1",
                "CP737",
                "WCP1257",
                "THAI",
                "CP720",
                "CP855",
                "CP857",
                "WCP1250",
                "CP775",
                "WCP1254",
                "WCP1255",
                "WCP1256",
                "WCP1258",
                "ISO_8859_2",
                "ISO_8859_3",
                "ISO_8859_4",
                "ISO_8859_5",
                "ISO_8859_6",
                "ISO_8859_7",
                "ISO_8859_8",
                "ISO_8859_9",
                "ISO_8859_15",
                "THAI_2",
                "CP856",
                "CP874",
                "TCVN3",
        };

        printerlibs_caysnpos.INSTANCE.CaysnPos_SetSingleByteMode(h);
        for (int i = 0; i < characterCodepageCode.length; ++i) {
            printerlibs_caysnpos.INSTANCE.CaysnPos_SetCharacterCodepage(h, characterCodepageCode[i]);
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, characterCodepageName[i]);
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);
            printerlibs_caysnpos.INSTANCE.CaysnPos_Write(h, chs, chs.length, 3000);
            printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 2);
        }
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置多字节模式
     * @param h
     */
    void onTest_CaysnPos_SetMultiByteMode(Pointer h) {
        byte[] data = new byte[]{(byte) 0xc4, (byte) 0xe3, (byte) 0xba, (byte) 0xc3};
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_GBK);
        printerlibs_caysnpos.INSTANCE.CaysnPos_Write(h, data, data.length, 1000);
        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 设置多字节编码
     * @param h
     */
    void onTest_CaysnPos_SetMultiByteEncoding(Pointer h) {
        onTest_CaysnPos_SetMultiByteMode(h);
    }

    /**
     * 从位图设置用户字符模式
     * @param h
     */
    void onTest_CaysnPos_SetUserCharacterPatternFromBitmap(Pointer h) {
        printerlibs_caysnpos.CaysnPos_SetUserCharacterPattern_Helper.CaysnPos_SetUserCharacterPatternFromBitmap(h, (byte) 'a', TestUtils.getImageFromAssetsFile(ctx, "UserCharacterSet12x24/a.bmp"));
        printerlibs_caysnpos.CaysnPos_SetUserCharacterPattern_Helper.CaysnPos_SetUserCharacterPatternFromBitmap(h, (byte) 'b', TestUtils.getImageFromAssetsFile(ctx, "UserCharacterSet12x24/b.bmp"));
        printerlibs_caysnpos.CaysnPos_SetUserCharacterPattern_Helper.CaysnPos_SetUserCharacterPatternFromBitmap(h, (byte) 'c', TestUtils.getImageFromAssetsFile(ctx, "UserCharacterSet12x24/c.bmp"));
        printerlibs_caysnpos.CaysnPos_SetUserCharacterPattern_Helper.CaysnPos_SetUserCharacterPatternFromBitmap(h, (byte) 'd', TestUtils.getImageFromAssetsFile(ctx, "UserCharacterSet12x24/d.bmp"));
        printerlibs_caysnpos.CaysnPos_SetUserCharacterPattern_Helper.CaysnPos_SetUserCharacterPatternFromBitmap(h, (byte) 'e', TestUtils.getImageFromAssetsFile(ctx, "UserCharacterSet12x24/e.bmp"));

        printerlibs_caysnpos.INSTANCE.CaysnPos_SetUserCharacterEnable(h, 1);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "abcdefghijklmnopqrstuvwxyz\r\n");
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetUserCharacterEnable(h, 0);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintTextA(h, "abcdefghijklmnopqrstuvwxyz\r\n");

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     *从位图设置用户汉字模式
     * @param h
     */
    void onTest_CaysnPos_SetUserKanjiPatternFromBitmap(Pointer h) {
        byte[] kanji = new byte[]{(byte) 0xfe, (byte) 0xa1};
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteMode(h);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetMultiByteEncoding(h, printerlibs_caysnpos.MultiByteModeEncoding_GBK);
        printerlibs_caysnpos.CaysnPos_SetUserKanjiPattern_Helper.CaysnPos_SetUserKanjiPatternFromBitmap(h, kanji[0], kanji[1], TestUtils.getImageFromAssetsFile(ctx, "UserKanji24x24/1.bmp"));

        printerlibs_caysnpos.INSTANCE.CaysnPos_Write(h, kanji, kanji.length, 1000);
        printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 1);

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 打印条形码
     * @param h
     */
    void onTest_CaysnPos_PrintBarcode(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetBarcodeUnitWidth(h, 2);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetBarcodeHeight(h, 60);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetBarcodeReadableTextFontType(h, printerlibs_caysnpos.BarcodeReadableTextFontType_Standard);
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetBarcodeReadableTextPosition(h, printerlibs_caysnpos.BarcodeReadableTextPosition_BelowBarcode);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeA(h, printerlibs_caysnpos.PosBarcodeType_UPCA, "01234567890");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeA(h, printerlibs_caysnpos.PosBarcodeType_UPCE, "123456");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeA(h, printerlibs_caysnpos.PosBarcodeType_EAN13, "123456789012");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeA(h, printerlibs_caysnpos.PosBarcodeType_EAN8, "1234567");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeA(h, printerlibs_caysnpos.PosBarcodeType_CODE39, "123456");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeA(h, printerlibs_caysnpos.PosBarcodeType_ITF, "123456");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeA(h, printerlibs_caysnpos.PosBarcodeType_CODEBAR, "A123456A");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeA(h, printerlibs_caysnpos.PosBarcodeType_CODE93, "123456");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeA(h, printerlibs_caysnpos.PosBarcodeType_CODE128, "No.123456");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintBarcodeW(h, printerlibs_caysnpos.PosBarcodeType_CODE128, new WString("No.123456"));

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 打印二维码
     * @param h
     */
    void onTest_CaysnPos_PrintQRCode(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_SetBarcodeUnitWidth(h, 8);
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintQRCodeA(h, 0, printerlibs_caysnpos.QRCodeECC_L, "Hello 欢迎使用");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintQRCodeW(h, 0, printerlibs_caysnpos.QRCodeECC_L, new WString("Hello 欢迎使用"));

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");

    }

    /**
     * 使用Epson Cmd打印二维码
     * @param h
     */
    void onTest_CaysnPos_PrintQRCodeUseEpsonCmd(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintQRCodeUseEpsonCmdA(h, 8, printerlibs_caysnpos.QRCodeECC_L, "Hello 欢迎使用");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintQRCodeUseEpsonCmdW(h, 8, printerlibs_caysnpos.QRCodeECC_L, new WString("Hello 欢迎使用"));

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");

    }

    /**
     * 打印双二维码
     * @param h
     */
    void onTest_CaysnPos_PrintDoubleQRCode(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintDoubleQRCodeA(h, 4, 0, 4, printerlibs_caysnpos.QRCodeECC_L, "hello", 200, 3, printerlibs_caysnpos.QRCodeECC_L, "test");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintDoubleQRCodeW(h, 4, 0, 4, printerlibs_caysnpos.QRCodeECC_L, new WString("hello"), 200, 3, printerlibs_caysnpos.QRCodeECC_L, new WString("测试"));

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");

    }

    /**
     * 使用Epson Cmd打印PDF417条形码
     * @param h
     */
    void onTest_CaysnPos_PrintPDF417BarcodeUseEpsonCmd(Pointer h) {
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintPDF417BarcodeUseEpsonCmdA(h, 0, 0, 3, 3, 0, 0, "test 测试");
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintPDF417BarcodeUseEpsonCmdW(h, 0, 0, 3, 3, 0, 0, new WString("test 测试"));

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");

    }

    /**
     * 打印光栅图像
     * @param h
     */
    void onTest_CaysnPos_PrintRasterImageFromBitmap(Pointer h) {
        Bitmap bitmap = TestUtils.getImageFromAssetsFile(ctx, "RasterImage/blackwhite.png");
        if (bitmap == null)
            return;

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        int page_width = 384;
        int dstw = width;
        int dsth = height;
        if (dstw > page_width) {
            dstw = page_width;
            dsth = (int)(dstw*((double)height/width));
        }

        printerlibs_caysnpos.CaysnPos_PrintRasterImage_Helper.CaysnPos_PrintRasterImageFromBitmap(h, dstw, dsth, bitmap, 0);

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 压缩打印光栅图像
     * @param h
     */
    void onTest_CaysnPos_PrintRasterImageWithCompressFromBitmap(Pointer h) {
        Bitmap bitmap = TestUtils.getImageFromAssetsFile(ctx, "RasterImage/yellowmen.png");
        if (bitmap == null)
            return;

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        int page_width = 384;
        int dstw = width;
        int dsth = height;
        if (dstw > page_width) {
            dstw = page_width;
            dsth = (int)(dstw*((double)height/width));
        }

        printerlibs_caysnpos.CaysnPos_PrintRasterImageWithCompress_Helper.CaysnPos_PrintRasterImageWithCompressFromBitmap(h, dstw, dsth, bitmap, 0, printerlibs_caysnpos.ImageCompressionMethod_Level1);

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 将点图像填充到当前行
     * @param h
     */
    void onTest_CaysnPos_FillDotImageToCurrentLineFromBitmap(Pointer h)
    {
        Bitmap bitmap = TestUtils.getImageFromAssetsFile(ctx, "FillDotImage/Kitty_76x30.bmp");
        if (bitmap == null)
            return;

        printerlibs_caysnpos.CaysnPos_FillDotImageToCurrentLine_Helper.CaysnPos_FillDotImageToCurrentLineFromBitmap(h, bitmap, printerlibs_caysnpos.ImageBinarizationMethod_Thresholding);

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 水平打印位图点图像
     * @param h
     */
    void onTest_CaysnPos_PrintDotImageSpecifyHorizontalPositionFromBitmap(Pointer h)
    {
        Bitmap bitmap = TestUtils.getImageFromAssetsFile(ctx, "NVImage/1.bmp");
        if (bitmap == null)
            return;

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        int page_width = 300;
        int dstw = width;
        int dsth = height;
        if (dstw > page_width) {
            dstw = page_width;
            dsth = (int)(dstw*((double)height/width));
        }

        printerlibs_caysnpos.CaysnPos_PrintDotImageSpecifyHorizontalPosition_Helper.CaysnPos_PrintDotImageSpecifyHorizontalPositionFromBitmap(h, 40, dstw, dsth, bitmap, 0);

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 打印水平线
     * @param h
     */
    void onTest_CaysnPos_PrintHorizontalLine(Pointer h)
    {
        for (int i = 0; i < 50; i += 1)
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintHorizontalLine(h, i, i + 100);
        for (int i = 50; i > 0; i -= 1)
            printerlibs_caysnpos.INSTANCE.CaysnPos_PrintHorizontalLine(h, i, i + 100);

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 打印水平线指定厚度
     * @param h
     */
    void onTest_CaysnPos_PrintHorizontalLineSpecifyThickness(Pointer h)
    {
        printerlibs_caysnpos.INSTANCE.CaysnPos_PrintHorizontalLineSpecifyThickness(h, 0, 200, 10);

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

    /**
     * 打印多个水平线箭头
     * @param h
     */
    void onTest_CaysnPos_PrintMultipleHorizontalLinesAtOneRow(Pointer h)
    {
        int r = 150;
        for (int y = -r; y <= r; ++y) {
            int x = (int) Math.sqrt(r*r-y*y);
            int x1 = -x+r;
            int x2 = x+r;
            int[] pLineStartPosition = new int[] { x1, x2 };
            int[] pLineEndPosition = new int[] { x1, x2 };
            if (printerlibs_caysnpos.INSTANCE.CaysnPos_PrintMultipleHorizontalLinesAtOneRow(h, 2, pLineStartPosition, pLineEndPosition) != 0)
                continue;
            else
                break;
        }

        int result = printerlibs_caysnpos.INSTANCE.CaysnPos_FeedLine(h, 3);
        if (result == 0)
            TestUtils.showMessageOnUiThread(ctx, "Write failed");
    }

}

class TestUtils {
    public static byte[] ReadFromFile(String fileName) {
        byte[] data = null;
        try {
            InputStream in = new FileInputStream(fileName);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (Throwable tr) {
            tr.printStackTrace();
        }

        return data;
    }

    public static Bitmap getImageFromAssetsFile(Context ctx, String fileName) {
        Bitmap image = null;
        AssetManager am = ctx.getResources().getAssets();
        try {
            InputStream is = am.open(fileName);
            image = BitmapFactory.decodeStream(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;
    }
    
    public static void showMessageOnUiThread(final Activity activity, final String msg) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
            }
        });
    }
}